package com.ruoyi.water.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.water.domain.Element;
import com.ruoyi.water.domain.IdCorrespond;
import com.ruoyi.water.domain.MeterData;
import com.ruoyi.water.domain.dto.ApiResponse;
import com.ruoyi.water.domain.dto.WaterMeterDataDTO;
import com.ruoyi.water.mapper.ElementMapper;
import com.ruoyi.water.mapper.IdCorrespondMapper;
import com.ruoyi.water.mapper.MeterDataMapper;
import com.ruoyi.water.service.IWaterMeterDataSyncService;
import com.ruoyi.water.service.WaterMeterDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 水表数据同步服务（修正关联关系：IdCorrespond.id查询，IdCorrespond.meterid存入结果）
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class WaterMeterDataSyncServiceImpl implements IWaterMeterDataSyncService {

    private final ElementMapper elementMapper;
    private final IdCorrespondMapper idCorrespondMapper;
    private final MeterDataMapper meterDataMapper;
    private final WaterMeterDataService waterMeterDataService;

    /**
     * 同步逻辑修正：
     * 1. Element.id → 关联 IdCorrespond.meterid
     * 2. 用 IdCorrespond.id 作为查询参数（meterIds）
     * 3. 结果存入 MeterData.meterid 时使用 IdCorrespond.meterid
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int syncMeterData(Date startTime, Date endTime) {
        // 1. 查询Element表所有记录
        List<Element> elements = elementMapper.selectList(null);
        if (elements.isEmpty()) {
            log.warn("Element表无数据，同步终止");
            return 0;
        }
        log.info("开始同步，共查询到{}条Element记录", elements.size());

        int totalSaved = 0;
        int totalDuplicates = 0;

        // 2. 遍历Element，关联IdCorrespond（Element.id = IdCorrespond.meterid）
        for (Element element : elements) {
            Long elementId = Long.valueOf(element.getId()); // Element的主键id

            // 查询条件：IdCorrespond.meterid = Element.id（核心关联修正）
            LambdaQueryWrapper<IdCorrespond> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(IdCorrespond::getMeterId, elementId.intValue());
            List<IdCorrespond> correspondList = idCorrespondMapper.selectList(queryWrapper);

            if (correspondList.isEmpty()) {
                log.info("ElementId={} 未匹配到IdCorrespond记录（meterid={}），跳过", elementId, elementId);
                continue;
            }

            // 3. 遍历匹配的IdCorrespond，用其id作为查询参数
            for (IdCorrespond correspond : correspondList) {
                Integer queryId = correspond.getId(); // 用于查询的id（节能平台meterIds参数）
                Integer targetMeterId = correspond.getMeterId(); // 最终要存入MeterData的meterid

                // 构建查询参数（用IdCorrespond.id作为meterIds）
                String queryParams = buildQueryParams(queryId, startTime, endTime);

                try {
                    // 4. 调用抄表接口（用queryId查询）
                    ApiResponse<List<WaterMeterDataDTO>> response =
                            waterMeterDataService.callEnergyPlatformRaw(queryParams);

                    List<WaterMeterDataDTO> meterDataDTOs = response.getData();
                    if (meterDataDTOs == null || meterDataDTOs.isEmpty()) {
                        log.info("查询Id={}（对应meterid={}）在时间范围[{}~{}]内无数据，跳过",
                                queryId, targetMeterId, formatDate(startTime), formatDate(endTime));
                        continue;
                    }

                    // 5. 转换数据：MeterData.meterid = IdCorrespond.meterid
                    List<MeterData> meterDataList = convertToMeterData(meterDataDTOs, targetMeterId, element);
                    int batchSize = meterDataList.size();

                    if (batchSize == 0) {
                        continue;
                    }

                    // 6. 批量保存（忽略重复记录）
                    int inserted = meterDataMapper.insertBatchIgnoreDuplicates(meterDataList);
                    totalSaved += inserted;
                    int duplicates = batchSize - inserted;
                    totalDuplicates += duplicates;

                    log.info("查询Id={}（对应meterid={}）处理完成，插入{}条数据，忽略{}条重复数据",
                            queryId, targetMeterId, inserted, duplicates);

                } catch (ServiceException e) {
                    log.error("查询Id={}（对应meterid={}）同步失败：{}", queryId, targetMeterId, e.getMessage());
                }
            }
        }

        log.info("水表数据同步完成，共成功插入{}条记录，忽略{}条重复记录", totalSaved, totalDuplicates);
        return totalSaved;
    }

    /**
     * 构建查询参数（用IdCorrespond.id作为meterIds）
     */
    private String buildQueryParams(Integer queryId, Date startTime, Date endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd%20HH:mm:ss");
        return String.format(
                "pageSize=99999999&meterDataType=1&meterIds=%d&startTime=%s&endTime=%s",
                queryId, // 核心：查询参数用IdCorrespond.id
                sdf.format(startTime),
                sdf.format(endTime)
        );
    }

    /**
     * 转换数据：MeterData.meterid设置为IdCorrespond.meterid
     */
    private List<MeterData> convertToMeterData(List<WaterMeterDataDTO> dataDTOs, Integer targetMeterId, Element element) {
        List<MeterData> result = new ArrayList<>();
        if (dataDTOs == null) {
            return result;
        }

        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (WaterMeterDataDTO dto : dataDTOs) {
            MeterData meterData = new MeterData();
            meterData.setMeterId(targetMeterId); // 存入IdCorrespond.meterid
            meterData.setMeterName(element.getElemName()); // 从Element取水表名称

            // 时间格式转换
            try {
                meterData.setReadTime(sdf.parse(dto.getTime()));
            } catch (ParseException e) {
                log.error("时间转换失败，time={}，默认设为当前时间", dto.getTime());
                meterData.setReadTime(now);
            }

            meterData.setReadValue(dto.getZvalueZY() != null ? dto.getZvalueZY() : 0L);
            meterData.setRecordTime(now);
            result.add(meterData);
        }
        return result;
    }

    /**
     * 日期格式化
     */
    private String formatDate(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }
}
